/**
 * 
 */
package org.vsg.stock.basic.persistence.hibernate;

import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.vsg.common.hibernate.AbstractGenericDaoImpl;
import org.vsg.common.hibernate.DateTransExtensionFunction;
import org.vsg.stock.basic.domain.StockPerformance;
import org.vsg.stock.basic.persistence.StockPerformanceDao;

/**
 * @author Bill Vison
 *
 */
public class StockPerformanceDaoImpl extends AbstractGenericDaoImpl implements
		StockPerformanceDao {

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.persistence.StockPerformanceDao#getStockPerformanceByCode(java.lang.String, java.util.Date)
	 */
	@Override
	public StockPerformance getStockPerformanceByCode(String stockCode,
			Date publishDate) throws DataAccessException {
		// TODO Auto-generated method stub
		StringBuilder query = new StringBuilder("SELECT ");
		query.append("stockPerformance ");
		query.append("from ").append(StockPerformance.class.getName());
		query.append(" as stockPerformance ");
		query.append("WHERE stockPerformance.stockCode = ? AND stockPerformance.publishDate <= ? AND stockPerformance.publishDate >= ? ");
		//query.append("ORDER BY stockDailyLine.date DESC");
		
		Collection paramColl = new Vector();
		paramColl.add( stockCode );
		paramColl.add( DateTransExtensionFunction.changeFirstTimeOfDate( publishDate ) );
		paramColl.add( DateTransExtensionFunction.changeLastTimeOfDate( publishDate ) );
		
		if (logger.isDebugEnabled()) {
			logger.debug("Execute SQL :"+query.toString());
		}
		Iterator<StockPerformance> iter = getTemplate().iterate(query.toString() , paramColl.toArray());
		
		StockPerformance sp = null;
		if ( iter.hasNext() ) {
			sp = iter.next();
		}		
		
		return sp;
	}

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.persistence.StockPerformanceDao#getStockPerformanceByCode(java.lang.String)
	 */
	@Override
	public List<StockPerformance> getStockPerformanceByCode(String stockCode)
			throws DataAccessException {
		// TODO Auto-generated method stub
		StringBuilder query = new StringBuilder("SELECT ");
		query.append("stockPerformance ");
		query.append("from ").append(StockPerformance.class.getName());
		query.append(" as stockPerformance ");
		query.append("WHERE stockPerformance.stockCode = ? ");
		query.append("ORDER BY stockPerformance.publishDate DESC");
		
		Collection paramColl = new Vector();
		paramColl.add( stockCode );
		
		if (logger.isDebugEnabled()) {
			logger.debug("Execute SQL :"+query.toString());
		}
		Iterator<StockPerformance> iter = getTemplate().iterate(query.toString() , paramColl.toArray());
		
		List<StockPerformance> list = new Vector<StockPerformance>();
		
		StockPerformance sp = null;
		while ( iter.hasNext() ) {
			sp = iter.next();
			list.add( sp );
		}		
		
		return list;
	}

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.persistence.StockPerformanceDao#saveAll(java.util.Collection)
	 */
	@Override
	public void saveAll(Collection<StockPerformance> entities)
			throws DataAccessException {
		// TODO Auto-generated method stub
		this.getTemplate().saveOrUpdateAll( entities );

	}

	@Override
	public void addAll(final Collection<StockPerformance> entities)
			throws DataAccessException {
		// TODO Auto-generated method stub
		
		final StringBuilder queryStr = new StringBuilder("INSERT INTO ");
		queryStr.append("stock_performance ");
		queryStr.append("(stock_code, publish_date, a_income, net_asset, a_reserve_fund, undistributed_profit) ");
		queryStr.append("SELECT  ");
		queryStr.append("? , ? , ? , ? , ? , ? ");
		queryStr.append("FROM stock_performance AS sp ");
		queryStr.append("WHERE sp.stock_code = ? AND sp.publish_date = ? ");
		queryStr.append("HAVING count(sp.id) = 0 ");

		HibernateCallback callBack = new HibernateCallback() {
			
			public Object doInHibernate(Session session) {

				logger.debug( queryStr.toString() );
				
				StockPerformance sp = null;
				
				int count = 0;
				Transaction tx = session.beginTransaction();
				tx.begin();

				for (Iterator<StockPerformance> entitiesIter = entities.iterator() ; entitiesIter.hasNext(); ) {
					sp = entitiesIter.next();
					
					Query query = session.createSQLQuery(queryStr.toString());
					query.setString(0, sp.getStockCode());
					query.setDate(1,sp.getPublishDate());
					query.setParameter (2, sp.getaIncome());
					query.setParameter(3, sp.getNetAsset());
					query.setParameter(4, sp.getaReserveFund());
					query.setParameter(5, sp.getUndistributedProfit());
					query.setString(6, sp.getStockCode());
					query.setDate(7,sp.getPublishDate());
					count+=query.executeUpdate();
					
					entitiesIter.remove();

				}
				
				tx.commit();

				return new Integer(count);
			}
		};
		
		this.getTemplate().execute(callBack);
		
		
	}

	
	
}
